package org.xtext.telcodev.dsl.generator;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.xtend2.lib.StringConcatenation;
import org.eclipse.xtext.generator.IFileSystemAccess;
import org.eclipse.xtext.generator.IGenerator;
import org.eclipse.xtext.xbase.lib.BooleanExtensions;
import org.eclipse.xtext.xbase.lib.IterableExtensions;
import org.eclipse.xtext.xbase.lib.ObjectExtensions;
import org.eclipse.xtext.xbase.lib.StringExtensions;
import org.xtext.telcodev.dsl.voiS.AbstractElement;
import org.xtext.telcodev.dsl.voiS.Ask;
import org.xtext.telcodev.dsl.voiS.Assigment;
import org.xtext.telcodev.dsl.voiS.Block;
import org.xtext.telcodev.dsl.voiS.BlockState;
import org.xtext.telcodev.dsl.voiS.BoolExpression;
import org.xtext.telcodev.dsl.voiS.BoolLiteral;
import org.xtext.telcodev.dsl.voiS.BoolVariable;
import org.xtext.telcodev.dsl.voiS.CompareExpression;
import org.xtext.telcodev.dsl.voiS.Concatenation;
import org.xtext.telcodev.dsl.voiS.ConcatenationExpression;
import org.xtext.telcodev.dsl.voiS.CondBlock;
import org.xtext.telcodev.dsl.voiS.CondStateBlock;
import org.xtext.telcodev.dsl.voiS.Dial;
import org.xtext.telcodev.dsl.voiS.Document;
import org.xtext.telcodev.dsl.voiS.GetDigits;
import org.xtext.telcodev.dsl.voiS.Hangup;
import org.xtext.telcodev.dsl.voiS.IfExp;
import org.xtext.telcodev.dsl.voiS.IfStateExp;
import org.xtext.telcodev.dsl.voiS.Literal;
import org.xtext.telcodev.dsl.voiS.LiteralAbs;
import org.xtext.telcodev.dsl.voiS.MathExpression;
import org.xtext.telcodev.dsl.voiS.NegExpression;
import org.xtext.telcodev.dsl.voiS.NumLiteral;
import org.xtext.telcodev.dsl.voiS.NumVariable;
import org.xtext.telcodev.dsl.voiS.Operation;
import org.xtext.telcodev.dsl.voiS.OperationBool;
import org.xtext.telcodev.dsl.voiS.Play;
import org.xtext.telcodev.dsl.voiS.Record;
import org.xtext.telcodev.dsl.voiS.Reject;
import org.xtext.telcodev.dsl.voiS.Save;
import org.xtext.telcodev.dsl.voiS.Say;
import org.xtext.telcodev.dsl.voiS.Send;
import org.xtext.telcodev.dsl.voiS.State;
import org.xtext.telcodev.dsl.voiS.StateAbstractElement;
import org.xtext.telcodev.dsl.voiS.Statement;
import org.xtext.telcodev.dsl.voiS.StringLiteral;
import org.xtext.telcodev.dsl.voiS.StringVariable;
import org.xtext.telcodev.dsl.voiS.Transition;
import org.xtext.telcodev.dsl.voiS.Vars;
import org.xtext.telcodev.dsl.voiS.VoiceTag;

@SuppressWarnings("all")
public class VoiSGenerator implements IGenerator {
  private String appName;
  
  private Set<String> variables;
  
  public void doGenerate(final Resource resource, final IFileSystemAccess fsa) {
      String _className = this.className(resource);
      this.appName = _className;
      HashSet<String> _hashSet = new HashSet<String>();
      this.variables = _hashSet;
      String _operator_plus = StringExtensions.operator_plus(this.appName, ".php");
      EList<EObject> _contents = resource.getContents();
      EObject _head = IterableExtensions.<EObject>head(_contents);
      CharSequence _tropoPHP = this.toTropoPHP(((Document) _head), resource);
      fsa.generateFile(_operator_plus, _tropoPHP);
  }
  
  public String className(final Resource res) {
      URI _uRI = res.getURI();
      String _lastSegment = _uRI.lastSegment();
      String name = _lastSegment;
      int _indexOf = name.indexOf(".");
      String _substring = name.substring(0, _indexOf);
      return _substring;
  }
  
  public CharSequence toTropoPHP(final Document sm, final Resource resource) {
    CharSequence _xifexpression = null;
    boolean _isStates = sm.isStates();
    boolean _operator_not = BooleanExtensions.operator_not(_isStates);
    if (_operator_not) {
      StringConcatenation _builder = new StringConcatenation();
      _builder.append("<?php");
      _builder.newLine();
      _builder.append("require \'tropo.class.php\';");
      _builder.newLine();
      _builder.append("require \'post_function.php\';");
      _builder.newLine();
      {
        EList<AbstractElement> _elements = sm.getElements();
        for(final AbstractElement c : _elements) {
          CharSequence _declareAbstractElement = this.declareAbstractElement(c);
          _builder.append(_declareAbstractElement, "");
          _builder.newLineIfNotEmpty();
        }
      }
      _builder.newLine();
      _builder.append("?>");
      _xifexpression = _builder;
    } else {
      StringConcatenation _builder_1 = new StringConcatenation();
      _builder_1.append("<?php");
      _builder_1.newLine();
      _builder_1.append("require \'tropo.class.php\';");
      _builder_1.newLine();
      _builder_1.append("require \'lib/limonade.php\';");
      _builder_1.newLine();
      _builder_1.append("require \'post_function.php\';");
      _builder_1.newLine();
      {
        EList<AbstractElement> _elements_1 = sm.getElements();
        for(final AbstractElement c_1 : _elements_1) {
          CharSequence _declareGlobalVariable = this.declareGlobalVariable(c_1);
          _builder_1.append(_declareGlobalVariable, "");
          _builder_1.newLineIfNotEmpty();
        }
      }
      {
        EList<State> _sta = sm.getSta();
        for(final State c_2 : _sta) {
          CharSequence _declareState = this.declareState(c_2);
          _builder_1.append(_declareState, "");
          _builder_1.newLineIfNotEmpty();
        }
      }
      _builder_1.append("run(); ");
      _builder_1.newLine();
      _builder_1.append("?>");
      _xifexpression = _builder_1;
    }
    return _xifexpression;
  }
  
  protected CharSequence _declareGlobalVariable(final Statement elem) {
    CharSequence _xblockexpression = null;
    {
      boolean _addGlobalVariable = this.addGlobalVariable(elem);
      boolean a = _addGlobalVariable;
      StringConcatenation _builder = new StringConcatenation();
      _xblockexpression = (_builder);
    }
    return _xblockexpression;
  }
  
  protected CharSequence _declareGlobalVariable(final IfExp elem) {
    StringConcatenation _builder = new StringConcatenation();
    return _builder;
  }
  
  protected boolean _addGlobalVariable(final BoolVariable elem) {
    String _name = elem.getName();
    boolean _add = this.variables.add(_name);
    return _add;
  }
  
  protected boolean _addGlobalVariable(final StringVariable elem) {
    String _name = elem.getName();
    boolean _add = this.variables.add(_name);
    return _add;
  }
  
  protected boolean _addGlobalVariable(final NumVariable elem) {
    String _name = elem.getName();
    boolean _add = this.variables.add(_name);
    return _add;
  }
  
  protected CharSequence _declareAbstractElement(final IfExp elem) {
    StringConcatenation _builder = new StringConcatenation();
    CondBlock _block = elem.getBlock();
    CharSequence _declareCondBlock = this.declareCondBlock(_block);
    _builder.append(_declareCondBlock, "");
    _builder.newLineIfNotEmpty();
    {
      EList<CondBlock> _blocks = elem.getBlocks();
      boolean _operator_notEquals = ObjectExtensions.operator_notEquals(_blocks, null);
      if (_operator_notEquals) {
        {
          EList<CondBlock> _blocks_1 = elem.getBlocks();
          for(final CondBlock e : _blocks_1) {
            _builder.append("else ");
            CharSequence _declareCondBlock_1 = this.declareCondBlock(e);
            _builder.append(_declareCondBlock_1, "");
          }
        }
      }
    }
    _builder.newLineIfNotEmpty();
    {
      Block _defaultBlock = elem.getDefaultBlock();
      boolean _operator_notEquals_1 = ObjectExtensions.operator_notEquals(_defaultBlock, null);
      if (_operator_notEquals_1) {
        _builder.append(" else ");
        Block _defaultBlock_1 = elem.getDefaultBlock();
        CharSequence _declareBlock = this.declareBlock(_defaultBlock_1);
        _builder.append(_declareBlock, "");
      }
    }
    return _builder;
  }
  
  protected CharSequence _declareAbstractElement(final Statement elem) {
    StringConcatenation _builder = new StringConcatenation();
    CharSequence _declareStatement = this.declareStatement(elem);
    _builder.append(_declareStatement, "");
    return _builder;
  }
  
  public CharSequence declareBlock(final Block elem) {
    StringConcatenation _builder = new StringConcatenation();
    _builder.append("{");
    {
      EList<AbstractElement> _stms = elem.getStms();
      boolean _isEmpty = _stms.isEmpty();
      boolean _operator_not = BooleanExtensions.operator_not(_isEmpty);
      if (_operator_not) {
        _builder.newLineIfNotEmpty();
        {
          EList<AbstractElement> _stms_1 = elem.getStms();
          for(final AbstractElement c : _stms_1) {
            CharSequence _declareAbstractElement = this.declareAbstractElement(c);
            _builder.append(_declareAbstractElement, "");
            _builder.newLineIfNotEmpty();
          }
        }
      }
    }
    _builder.append("\t\t");
    _builder.append("}");
    return _builder;
  }
  
  public CharSequence declareCondBlock(final CondBlock elem) {
    StringConcatenation _builder = new StringConcatenation();
    _builder.append("if(");
    BoolExpression _cond = elem.getCond();
    CharSequence _declareBoolExpression = this.declareBoolExpression(_cond);
    _builder.append(_declareBoolExpression, "");
    _builder.append(")");
    Block _action = elem.getAction();
    CharSequence _declareBlock = this.declareBlock(_action);
    _builder.append(_declareBlock, "");
    return _builder;
  }
  
  protected CharSequence _declareBoolExpression(final BoolLiteral elem) {
    StringConcatenation _builder = new StringConcatenation();
    String _value = elem.getValue();
    _builder.append(_value, "");
    return _builder;
  }
  
  protected CharSequence _declareBoolExpression(final Literal elem) {
    StringConcatenation _builder = new StringConcatenation();
    CharSequence _declareLiteral = this.declareLiteral(elem);
    _builder.append(_declareLiteral, "");
    return _builder;
  }
  
  protected CharSequence _declareBoolExpression(final CompareExpression elem) {
    StringConcatenation _builder = new StringConcatenation();
    LiteralAbs _left = elem.getLeft();
    CharSequence _declareLiteral = this.declareLiteral(_left);
    _builder.append(_declareLiteral, "");
    String _op = elem.getOp();
    _builder.append(_op, "");
    LiteralAbs _right = elem.getRight();
    CharSequence _declareLiteral_1 = this.declareLiteral(_right);
    _builder.append(_declareLiteral_1, "");
    return _builder;
  }
  
  protected CharSequence _declareBoolExpression(final NegExpression elem) {
    StringConcatenation _builder = new StringConcatenation();
    String _op = elem.getOp();
    _builder.append(_op, "");
    BoolExpression _obj = elem.getObj();
    CharSequence _declareBoolExpression = this.declareBoolExpression(_obj);
    _builder.append(_declareBoolExpression, "");
    return _builder;
  }
  
  protected CharSequence _declareBoolExpression(final OperationBool elem) {
    StringConcatenation _builder = new StringConcatenation();
    BoolExpression _left = elem.getLeft();
    CharSequence _declareBoolExpression = this.declareBoolExpression(_left);
    _builder.append(_declareBoolExpression, "");
    String _op = elem.getOp();
    _builder.append(_op, "");
    BoolExpression _right = elem.getRight();
    CharSequence _declareBoolExpression_1 = this.declareBoolExpression(_right);
    _builder.append(_declareBoolExpression_1, "");
    return _builder;
  }
  
  protected CharSequence _declareMathExpression(final Operation elem) {
    StringConcatenation _builder = new StringConcatenation();
    MathExpression _left = elem.getLeft();
    CharSequence _declareMathExpression = this.declareMathExpression(_left);
    _builder.append(_declareMathExpression, "");
    String _op = elem.getOp();
    _builder.append(_op, "");
    MathExpression _right = elem.getRight();
    CharSequence _declareMathExpression_1 = this.declareMathExpression(_right);
    _builder.append(_declareMathExpression_1, "");
    return _builder;
  }
  
  protected CharSequence _declareMathExpression(final Literal elem) {
    StringConcatenation _builder = new StringConcatenation();
    CharSequence _declareLiteral = this.declareLiteral(elem);
    _builder.append(_declareLiteral, "");
    return _builder;
  }
  
  protected CharSequence _declareConcatenation(final Concatenation elem) {
    StringConcatenation _builder = new StringConcatenation();
    ConcatenationExpression _left = elem.getLeft();
    CharSequence _declareConcatenation = this.declareConcatenation(_left);
    _builder.append(_declareConcatenation, "");
    _builder.append(".");
    ConcatenationExpression _right = elem.getRight();
    CharSequence _declareConcatenation_1 = this.declareConcatenation(_right);
    _builder.append(_declareConcatenation_1, "");
    return _builder;
  }
  
  protected CharSequence _declareConcatenation(final LiteralAbs elem) {
    StringConcatenation _builder = new StringConcatenation();
    CharSequence _declareLiteralAbs = this.declareLiteralAbs(elem);
    _builder.append(_declareLiteralAbs, "");
    return _builder;
  }
  
  protected CharSequence _declareVars(final StringVariable elem) {
    StringConcatenation _builder = new StringConcatenation();
    String _name = elem.getName();
    _builder.append(_name, "");
    return _builder;
  }
  
  protected CharSequence _declareVars(final BoolVariable elem) {
    StringConcatenation _builder = new StringConcatenation();
    String _name = elem.getName();
    _builder.append(_name, "");
    return _builder;
  }
  
  protected CharSequence _declareVars(final NumVariable elem) {
    StringConcatenation _builder = new StringConcatenation();
    String _name = elem.getName();
    _builder.append(_name, "");
    return _builder;
  }
  
  protected CharSequence _declareVars(final Ask elem) {
    StringConcatenation _builder = new StringConcatenation();
    String _name = elem.getName();
    _builder.append(_name, "");
    return _builder;
  }
  
  protected CharSequence _declareVars(final GetDigits elem) {
    StringConcatenation _builder = new StringConcatenation();
    String _name = elem.getName();
    _builder.append(_name, "");
    return _builder;
  }
  
  public CharSequence declareAssigment(final Assigment elem) {
    CharSequence _xifexpression = null;
    Vars _va = elem.getVa();
    CharSequence _declareVars = this.declareVars(_va);
    String _string = _declareVars.toString();
    boolean _contains = this.variables.contains(_string);
    if (_contains) {
      StringConcatenation _builder = new StringConcatenation();
      _builder.append("$");
      Vars _va_1 = elem.getVa();
      CharSequence _declareVars_1 = this.declareVars(_va_1);
      _builder.append(_declareVars_1, "");
      _builder.append("=");
      MathExpression _right = elem.getRight();
      CharSequence _declareMathExpression = this.declareMathExpression(_right);
      _builder.append(_declareMathExpression, "");
      _builder.append(";");
      _builder.newLineIfNotEmpty();
      _builder.append("$_SESSION[\'");
      Vars _va_2 = elem.getVa();
      CharSequence _declareVars_2 = this.declareVars(_va_2);
      _builder.append(_declareVars_2, "");
      _builder.append("\'] = $");
      Vars _va_3 = elem.getVa();
      CharSequence _declareVars_3 = this.declareVars(_va_3);
      _builder.append(_declareVars_3, "");
      _xifexpression = _builder;
    } else {
      StringConcatenation _builder_1 = new StringConcatenation();
      _builder_1.append("$");
      Vars _va_4 = elem.getVa();
      CharSequence _declareVars_4 = this.declareVars(_va_4);
      _builder_1.append(_declareVars_4, "");
      _builder_1.append("=");
      MathExpression _right_1 = elem.getRight();
      CharSequence _declareMathExpression_1 = this.declareMathExpression(_right_1);
      _builder_1.append(_declareMathExpression_1, "");
      _xifexpression = _builder_1;
    }
    return _xifexpression;
  }
  
  public CharSequence declareVariable(final StringVariable elem) {
    StringConcatenation _builder = new StringConcatenation();
    _builder.append("$");
    String _name = elem.getName();
    _builder.append(_name, "");
    {
      ConcatenationExpression _value = elem.getValue();
      boolean _operator_notEquals = ObjectExtensions.operator_notEquals(_value, null);
      if (_operator_notEquals) {
        _builder.append("=");
        ConcatenationExpression _value_1 = elem.getValue();
        CharSequence _declareConcatenation = this.declareConcatenation(_value_1);
        _builder.append(_declareConcatenation, "");
      }
    }
    return _builder;
  }
  
  public CharSequence declareVariable(final NumVariable elem) {
    StringConcatenation _builder = new StringConcatenation();
    _builder.append("$");
    String _name = elem.getName();
    _builder.append(_name, "");
    {
      MathExpression _value = elem.getValue();
      boolean _operator_notEquals = ObjectExtensions.operator_notEquals(_value, null);
      if (_operator_notEquals) {
        _builder.append("=");
        MathExpression _value_1 = elem.getValue();
        CharSequence _declareMathExpression = this.declareMathExpression(_value_1);
        _builder.append(_declareMathExpression, "");
      }
    }
    return _builder;
  }
  
  public CharSequence declareVariable(final BoolVariable elem) {
    StringConcatenation _builder = new StringConcatenation();
    _builder.append("$");
    String _name = elem.getName();
    _builder.append(_name, "");
    {
      BoolExpression _value = elem.getValue();
      boolean _operator_notEquals = ObjectExtensions.operator_notEquals(_value, null);
      if (_operator_notEquals) {
        _builder.append("=");
        BoolExpression _value_1 = elem.getValue();
        CharSequence _declareBoolExpression = this.declareBoolExpression(_value_1);
        _builder.append(_declareBoolExpression, "");
      }
    }
    return _builder;
  }
  
  protected CharSequence _declareLiteralAbs(final StringLiteral elem) {
    StringConcatenation _builder = new StringConcatenation();
    String _value = elem.getValue();
    _builder.append(_value, "");
    return _builder;
  }
  
  protected CharSequence _declareLiteralAbs(final Literal elem) {
    StringConcatenation _builder = new StringConcatenation();
    CharSequence _declareLiteral = this.declareLiteral(elem);
    _builder.append(_declareLiteral, "");
    return _builder;
  }
  
  protected CharSequence _declareLiteralAbs(final BoolLiteral elem) {
    StringConcatenation _builder = new StringConcatenation();
    String _value = elem.getValue();
    _builder.append(_value, "");
    return _builder;
  }
  
  protected CharSequence _declareLiteral(final StringLiteral elem) {
    StringConcatenation _builder = new StringConcatenation();
    _builder.append("\"");
    String _value = elem.getValue();
    _builder.append(_value, "");
    _builder.append("\"");
    return _builder;
  }
  
  protected CharSequence _declareLiteral(final Literal elem) {
    CharSequence _xifexpression = null;
    Vars _v = elem.getV();
    boolean _operator_notEquals = ObjectExtensions.operator_notEquals(_v, null);
    if (_operator_notEquals) {
      StringConcatenation _builder = new StringConcatenation();
      _builder.append("$");
      Vars _v_1 = elem.getV();
      CharSequence _declareVars = this.declareVars(_v_1);
      _builder.append(_declareVars, "");
      _xifexpression = _builder;
    } else {
      CharSequence _xifexpression_1 = null;
      String _nul = elem.getNul();
      boolean _operator_notEquals_1 = ObjectExtensions.operator_notEquals(_nul, null);
      if (_operator_notEquals_1) {
        StringConcatenation _builder_1 = new StringConcatenation();
        _builder_1.append("null");
        _xifexpression_1 = _builder_1;
      } else {
        StringConcatenation _builder_2 = new StringConcatenation();
        _builder_2.append("$");
        String _ses = elem.getSes();
        _builder_2.append(_ses, "");
        _xifexpression_1 = _builder_2;
      }
      _xifexpression = _xifexpression_1;
    }
    return _xifexpression;
  }
  
  protected CharSequence _declareLiteral(final NumLiteral elem) {
    StringConcatenation _builder = new StringConcatenation();
    String _value = elem.getValue();
    _builder.append(_value, "");
    return _builder;
  }
  
  protected CharSequence _declareVoiceTag(final Send elem) {
    StringConcatenation _builder = new StringConcatenation();
    _builder.append("$resultSend = post_request(\'");
    ConcatenationExpression _uri = elem.getUri();
    CharSequence _declareConcatenation = this.declareConcatenation(_uri);
    _builder.append(_declareConcatenation, "");
    _builder.append("\', array(\"");
    String _name = elem.getName();
    _builder.append(_name, "");
    _builder.append("\"=>");
    ConcatenationExpression _that = elem.getThat();
    CharSequence _declareConcatenation_1 = this.declareConcatenation(_that);
    _builder.append(_declareConcatenation_1, "");
    _builder.append(");");
    return _builder;
  }
  
  protected CharSequence _declareVoiceTag(final Say elem) {
    StringConcatenation _builder = new StringConcatenation();
    _builder.append("$tropo->say(");
    ConcatenationExpression _that = elem.getThat();
    CharSequence _declareConcatenation = this.declareConcatenation(_that);
    _builder.append(_declareConcatenation, "");
    _builder.append(")");
    return _builder;
  }
  
  protected CharSequence _declareVoiceTag(final Ask elem) {
    StringConcatenation _builder = new StringConcatenation();
    _builder.append("$");
    String _name = elem.getName();
    _builder.append(_name, "");
    _builder.append("=$tropo->ask(");
    ConcatenationExpression _question = elem.getQuestion();
    CharSequence _declareConcatenation = this.declareConcatenation(_question);
    _builder.append(_declareConcatenation, "");
    _builder.append(", array(\"choices\" => \"");
    String _choices = elem.getChoices();
    _builder.append(_choices, "");
    _builder.append("\", \"name\"=>\"");
    String _name_1 = elem.getName();
    _builder.append(_name_1, "");
    _builder.append("\"))");
    return _builder;
  }
  
  protected CharSequence _declareVoiceTag(final Play elem) {
    StringConcatenation _builder = new StringConcatenation();
    _builder.append("$tropo->say(");
    ConcatenationExpression _file = elem.getFile();
    CharSequence _declareConcatenation = this.declareConcatenation(_file);
    _builder.append(_declareConcatenation, "");
    _builder.append(")");
    return _builder;
  }
  
  protected CharSequence _declareVoiceTag(final Record elem) {
    StringConcatenation _builder = new StringConcatenation();
    _builder.append("$tropo->record(array(\'url\' => \'");
    ConcatenationExpression _action = elem.getAction();
    CharSequence _declareConcatenation = this.declareConcatenation(_action);
    _builder.append(_declareConcatenation, "");
    _builder.append("\',\'terminator\' => \'#\'");
    {
      int _time = elem.getTime();
      boolean _operator_notEquals = ObjectExtensions.operator_notEquals(Integer.valueOf(_time), null);
      if (_operator_notEquals) {
        _builder.append(",\'timeout\' =>");
        int _time_1 = elem.getTime();
        _builder.append(_time_1, "");
        _builder.append(")");
      }
    }
    _builder.append(" )");
    return _builder;
  }
  
  protected CharSequence _declareVoiceTag(final Reject elem) {
    StringConcatenation _builder = new StringConcatenation();
    _builder.append("$tropo->reject()");
    return _builder;
  }
  
  protected CharSequence _declareVoiceTag(final Hangup elem) {
    StringConcatenation _builder = new StringConcatenation();
    _builder.append("$tropo->hangup()");
    return _builder;
  }
  
  protected CharSequence _declareVoiceTag(final GetDigits elem) {
    StringConcatenation _builder = new StringConcatenation();
    _builder.append("$");
    String _name = elem.getName();
    _builder.append(_name, "");
    _builder.append("=$tropo->ask(");
    ConcatenationExpression _question = elem.getQuestion();
    CharSequence _declareConcatenation = this.declareConcatenation(_question);
    _builder.append(_declareConcatenation, "");
    _builder.append(",array(\"choices\"=>[");
    int _numDigits = elem.getNumDigits();
    _builder.append(_numDigits, "");
    _builder.append(" DIGITS]\", \"terminator\" => \"#\", \"name\"=>\"");
    String _name_1 = elem.getName();
    _builder.append(_name_1, "");
    _builder.append("\"))");
    return _builder;
  }
  
  protected CharSequence _declareVoiceTag(final Dial elem) {
    StringConcatenation _builder = new StringConcatenation();
    _builder.append("$tropo->transfer(\"");
    ConcatenationExpression _to = elem.getTo();
    CharSequence _declareConcatenation = this.declareConcatenation(_to);
    _builder.append(_declareConcatenation, "");
    _builder.append("\")");
    return _builder;
  }
  
  protected CharSequence _declareStatement(final StringVariable elem) {
    StringConcatenation _builder = new StringConcatenation();
    CharSequence _declareVariable = this.declareVariable(elem);
    _builder.append(_declareVariable, "");
    _builder.append(";");
    return _builder;
  }
  
  protected CharSequence _declareStatement(final NumVariable elem) {
    StringConcatenation _builder = new StringConcatenation();
    CharSequence _declareVariable = this.declareVariable(elem);
    _builder.append(_declareVariable, "");
    _builder.append(";");
    return _builder;
  }
  
  protected CharSequence _declareStatement(final Assigment elem) {
    StringConcatenation _builder = new StringConcatenation();
    CharSequence _declareAssigment = this.declareAssigment(elem);
    _builder.append(_declareAssigment, "");
    _builder.append(";");
    return _builder;
  }
  
  protected CharSequence _declareStatement(final BoolVariable elem) {
    StringConcatenation _builder = new StringConcatenation();
    CharSequence _declareVariable = this.declareVariable(elem);
    _builder.append(_declareVariable, "");
    _builder.append(";");
    return _builder;
  }
  
  protected CharSequence _declareStatement(final VoiceTag elem) {
    StringConcatenation _builder = new StringConcatenation();
    CharSequence _declareVoiceTag = this.declareVoiceTag(elem);
    _builder.append(_declareVoiceTag, "");
    _builder.append(";");
    return _builder;
  }
  
  protected CharSequence _declareTransition(final Transition elem) {
    StringConcatenation _builder = new StringConcatenation();
    _builder.append("$tropo->on(array(\"event\" => \"");
    String _event = elem.getEvent();
    _builder.append(_event, "");
    _builder.append("\", \"next\" =>\"");
    _builder.append(this.appName, "");
    _builder.append(".php?uri=");
    State _target = elem.getTarget();
    String _name = _target.getName();
    _builder.append(_name, "");
    _builder.append("\"));");
    return _builder;
  }
  
  protected CharSequence _declareState(final State elem) {
    StringConcatenation _builder = new StringConcatenation();
    _builder.append("dispatch_post(\'/");
    String _name = elem.getName();
    _builder.append(_name, "");
    _builder.append("\', \'app_");
    String _name_1 = elem.getName();
    _builder.append(_name_1, "");
    _builder.append("\');");
    _builder.newLineIfNotEmpty();
    _builder.append("function app_");
    String _name_2 = elem.getName();
    _builder.append(_name_2, "");
    _builder.append("() {");
    _builder.newLineIfNotEmpty();
    _builder.append("\t");
    _builder.append("$session = new Session();");
    _builder.newLine();
    _builder.append("\t");
    _builder.append("$from_info = $session->getFrom();");
    _builder.newLine();
    _builder.append("\t");
    _builder.append("$caller = $from[\"id\"]; ");
    _builder.newLine();
    _builder.append("\t");
    _builder.append("$tropo = new Tropo();");
    {
      for(final String d : this.variables) {
        _builder.newLineIfNotEmpty();
        _builder.append("\t");
        CharSequence _declareGlobalVariable = this.declareGlobalVariable(d);
        _builder.append(_declareGlobalVariable, "	");
        _builder.append(" ");
        _builder.newLineIfNotEmpty();
      }
    }
    {
      EList<StateAbstractElement> _stms = elem.getStms();
      for(final StateAbstractElement c : _stms) {
        _builder.append("\t");
        CharSequence _declareStateAbstractElement = this.declareStateAbstractElement(c);
        _builder.append(_declareStateAbstractElement, "	");
        _builder.newLineIfNotEmpty();
      }
    }
    _builder.append("\t");
    _builder.append("return $tropo->RenderJson();");
    _builder.newLine();
    _builder.append("}");
    return _builder;
  }
  
  public CharSequence declareGlobalVariable(final String elem) {
    StringConcatenation _builder = new StringConcatenation();
    _builder.append("$");
    _builder.append(elem, "");
    _builder.append("=$_SESSION[\'");
    _builder.append(elem, "");
    _builder.append("\'];");
    return _builder;
  }
  
  public CharSequence declareSave(final Save elem) {
    CharSequence _xblockexpression = null;
    {
      Vars _that = elem.getThat();
      CharSequence _declareVars = this.declareVars(_that);
      String _string = _declareVars.toString();
      this.variables.add(_string);
      StringConcatenation _builder = new StringConcatenation();
      _builder.append("$_SESSION[\'");
      Vars _that_1 = elem.getThat();
      CharSequence _declareVars_1 = this.declareVars(_that_1);
      _builder.append(_declareVars_1, "");
      _builder.append("\'] = $");
      Vars _that_2 = elem.getThat();
      CharSequence _declareVars_2 = this.declareVars(_that_2);
      _builder.append(_declareVars_2, "");
      _builder.append(";");
      _xblockexpression = (_builder);
    }
    return _xblockexpression;
  }
  
  protected CharSequence _declareStateAbstractElement(final IfStateExp elem) {
    StringConcatenation _builder = new StringConcatenation();
    CharSequence _declareStateStructure = this.declareStateStructure(elem);
    _builder.append(_declareStateStructure, "");
    return _builder;
  }
  
  protected CharSequence _declareStateAbstractElement(final Statement elem) {
    StringConcatenation _builder = new StringConcatenation();
    CharSequence _declareStatement = this.declareStatement(elem);
    _builder.append(_declareStatement, "");
    return _builder;
  }
  
  protected CharSequence _declareStateAbstractElement(final Save elem) {
    StringConcatenation _builder = new StringConcatenation();
    CharSequence _declareSave = this.declareSave(elem);
    _builder.append(_declareSave, "");
    return _builder;
  }
  
  protected CharSequence _declareStateAbstractElement(final Transition elem) {
    StringConcatenation _builder = new StringConcatenation();
    CharSequence _declareTransition = this.declareTransition(elem);
    _builder.append(_declareTransition, "");
    return _builder;
  }
  
  public CharSequence declareStateStructure(final IfStateExp elem) {
    StringConcatenation _builder = new StringConcatenation();
    CondStateBlock _block = elem.getBlock();
    CharSequence _declareCondStateBlock = this.declareCondStateBlock(_block);
    _builder.append(_declareCondStateBlock, "");
    _builder.newLineIfNotEmpty();
    {
      EList<CondStateBlock> _blocks = elem.getBlocks();
      boolean _operator_notEquals = ObjectExtensions.operator_notEquals(_blocks, null);
      if (_operator_notEquals) {
        {
          EList<CondStateBlock> _blocks_1 = elem.getBlocks();
          for(final CondStateBlock e : _blocks_1) {
            _builder.append("else ");
            CharSequence _declareCondStateBlock_1 = this.declareCondStateBlock(e);
            _builder.append(_declareCondStateBlock_1, "");
          }
        }
      }
    }
    _builder.newLineIfNotEmpty();
    {
      BlockState _defaultBlock = elem.getDefaultBlock();
      boolean _operator_notEquals_1 = ObjectExtensions.operator_notEquals(_defaultBlock, null);
      if (_operator_notEquals_1) {
        _builder.append("else ");
        BlockState _defaultBlock_1 = elem.getDefaultBlock();
        CharSequence _declareStateBlock = this.declareStateBlock(_defaultBlock_1);
        _builder.append(_declareStateBlock, "");
      }
    }
    return _builder;
  }
  
  public CharSequence declareStateBlock(final BlockState elem) {
    StringConcatenation _builder = new StringConcatenation();
    _builder.append("{");
    _builder.newLine();
    {
      EList<StateAbstractElement> _sta = elem.getSta();
      for(final StateAbstractElement c : _sta) {
        CharSequence _declareStateAbstractElement = this.declareStateAbstractElement(c);
        _builder.append(_declareStateAbstractElement, "");
        _builder.newLineIfNotEmpty();
      }
    }
    _builder.append("\t\t");
    _builder.append("}");
    return _builder;
  }
  
  public CharSequence declareCondStateBlock(final CondStateBlock elem) {
    StringConcatenation _builder = new StringConcatenation();
    _builder.append("if(");
    BoolExpression _cond = elem.getCond();
    CharSequence _declareBoolExpression = this.declareBoolExpression(_cond);
    _builder.append(_declareBoolExpression, "");
    _builder.append(")");
    BlockState _action = elem.getAction();
    CharSequence _declareStateBlock = this.declareStateBlock(_action);
    _builder.append(_declareStateBlock, "");
    return _builder;
  }
  
  public CharSequence declareGlobalVariable(final AbstractElement elem) {
    if (elem instanceof IfExp) {
      return _declareGlobalVariable((IfExp)elem);
    } else if (elem instanceof Statement) {
      return _declareGlobalVariable((Statement)elem);
    } else {
      throw new IllegalArgumentException("Unhandled parameter types: " +
        Arrays.<Object>asList(elem).toString());
    }
  }
  
  public boolean addGlobalVariable(final EObject elem) {
    if (elem instanceof BoolVariable) {
      return _addGlobalVariable((BoolVariable)elem);
    } else if (elem instanceof NumVariable) {
      return _addGlobalVariable((NumVariable)elem);
    } else if (elem instanceof StringVariable) {
      return _addGlobalVariable((StringVariable)elem);
    } else {
      throw new IllegalArgumentException("Unhandled parameter types: " +
        Arrays.<Object>asList(elem).toString());
    }
  }
  
  public CharSequence declareAbstractElement(final AbstractElement elem) {
    if (elem instanceof IfExp) {
      return _declareAbstractElement((IfExp)elem);
    } else if (elem instanceof Statement) {
      return _declareAbstractElement((Statement)elem);
    } else {
      throw new IllegalArgumentException("Unhandled parameter types: " +
        Arrays.<Object>asList(elem).toString());
    }
  }
  
  public CharSequence declareBoolExpression(final BoolExpression elem) {
    if (elem instanceof BoolLiteral) {
      return _declareBoolExpression((BoolLiteral)elem);
    } else if (elem instanceof Literal) {
      return _declareBoolExpression((Literal)elem);
    } else if (elem instanceof CompareExpression) {
      return _declareBoolExpression((CompareExpression)elem);
    } else if (elem instanceof NegExpression) {
      return _declareBoolExpression((NegExpression)elem);
    } else if (elem instanceof OperationBool) {
      return _declareBoolExpression((OperationBool)elem);
    } else {
      throw new IllegalArgumentException("Unhandled parameter types: " +
        Arrays.<Object>asList(elem).toString());
    }
  }
  
  public CharSequence declareMathExpression(final MathExpression elem) {
    if (elem instanceof Literal) {
      return _declareMathExpression((Literal)elem);
    } else if (elem instanceof Operation) {
      return _declareMathExpression((Operation)elem);
    } else {
      throw new IllegalArgumentException("Unhandled parameter types: " +
        Arrays.<Object>asList(elem).toString());
    }
  }
  
  public CharSequence declareConcatenation(final ConcatenationExpression elem) {
    if (elem instanceof Concatenation) {
      return _declareConcatenation((Concatenation)elem);
    } else if (elem instanceof LiteralAbs) {
      return _declareConcatenation((LiteralAbs)elem);
    } else {
      throw new IllegalArgumentException("Unhandled parameter types: " +
        Arrays.<Object>asList(elem).toString());
    }
  }
  
  public CharSequence declareVars(final Vars elem) {
    if (elem instanceof Ask) {
      return _declareVars((Ask)elem);
    } else if (elem instanceof GetDigits) {
      return _declareVars((GetDigits)elem);
    } else if (elem instanceof BoolVariable) {
      return _declareVars((BoolVariable)elem);
    } else if (elem instanceof NumVariable) {
      return _declareVars((NumVariable)elem);
    } else if (elem instanceof StringVariable) {
      return _declareVars((StringVariable)elem);
    } else {
      throw new IllegalArgumentException("Unhandled parameter types: " +
        Arrays.<Object>asList(elem).toString());
    }
  }
  
  public CharSequence declareLiteralAbs(final LiteralAbs elem) {
    if (elem instanceof BoolLiteral) {
      return _declareLiteralAbs((BoolLiteral)elem);
    } else if (elem instanceof Literal) {
      return _declareLiteralAbs((Literal)elem);
    } else if (elem instanceof StringLiteral) {
      return _declareLiteralAbs((StringLiteral)elem);
    } else {
      throw new IllegalArgumentException("Unhandled parameter types: " +
        Arrays.<Object>asList(elem).toString());
    }
  }
  
  public CharSequence declareLiteral(final LiteralAbs elem) {
    if (elem instanceof NumLiteral) {
      return _declareLiteral((NumLiteral)elem);
    } else if (elem instanceof Literal) {
      return _declareLiteral((Literal)elem);
    } else if (elem instanceof StringLiteral) {
      return _declareLiteral((StringLiteral)elem);
    } else {
      throw new IllegalArgumentException("Unhandled parameter types: " +
        Arrays.<Object>asList(elem).toString());
    }
  }
  
  public CharSequence declareVoiceTag(final VoiceTag elem) {
    if (elem instanceof Ask) {
      return _declareVoiceTag((Ask)elem);
    } else if (elem instanceof Dial) {
      return _declareVoiceTag((Dial)elem);
    } else if (elem instanceof GetDigits) {
      return _declareVoiceTag((GetDigits)elem);
    } else if (elem instanceof Hangup) {
      return _declareVoiceTag((Hangup)elem);
    } else if (elem instanceof Play) {
      return _declareVoiceTag((Play)elem);
    } else if (elem instanceof Record) {
      return _declareVoiceTag((Record)elem);
    } else if (elem instanceof Reject) {
      return _declareVoiceTag((Reject)elem);
    } else if (elem instanceof Say) {
      return _declareVoiceTag((Say)elem);
    } else if (elem instanceof Send) {
      return _declareVoiceTag((Send)elem);
    } else {
      throw new IllegalArgumentException("Unhandled parameter types: " +
        Arrays.<Object>asList(elem).toString());
    }
  }
  
  public CharSequence declareStatement(final Statement elem) {
    if (elem instanceof Assigment) {
      return _declareStatement((Assigment)elem);
    } else if (elem instanceof BoolVariable) {
      return _declareStatement((BoolVariable)elem);
    } else if (elem instanceof NumVariable) {
      return _declareStatement((NumVariable)elem);
    } else if (elem instanceof StringVariable) {
      return _declareStatement((StringVariable)elem);
    } else if (elem instanceof VoiceTag) {
      return _declareStatement((VoiceTag)elem);
    } else {
      throw new IllegalArgumentException("Unhandled parameter types: " +
        Arrays.<Object>asList(elem).toString());
    }
  }
  
  public CharSequence declareTransition(final Transition elem) {
    {
      return _declareTransition(elem);
    }
  }
  
  public CharSequence declareState(final State elem) {
    {
      return _declareState(elem);
    }
  }
  
  public CharSequence declareStateAbstractElement(final StateAbstractElement elem) {
    if (elem instanceof IfStateExp) {
      return _declareStateAbstractElement((IfStateExp)elem);
    } else if (elem instanceof Save) {
      return _declareStateAbstractElement((Save)elem);
    } else if (elem instanceof Statement) {
      return _declareStateAbstractElement((Statement)elem);
    } else if (elem instanceof Transition) {
      return _declareStateAbstractElement((Transition)elem);
    } else {
      throw new IllegalArgumentException("Unhandled parameter types: " +
        Arrays.<Object>asList(elem).toString());
    }
  }
}
